﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.ComponentModel;

namespace BDSim
{
    [TypeConverter(typeof(PropertySorter))]   
    public class SendReceiveDevice : BDSimObject
    {
        public SendReceiveDevice()
        {
            DataProvider.Parent = this;
            DataProvider.DefineCommand();
            this.Menu.ItemsSource = DataProvider.MenuCommandList;
        }

        #region 字段        
        private double _Elelim = 10;          // 观测截止仰角(0~30) 
        private double _Freq = 12345;         // 频点               
        [XmlIgnore]
        public StationCollection Parent;      //同一类型站集
        [XmlIgnore]
        public StationBase Parent2;

        private ObsReceiverInPut ObsInput;

        [XmlIgnore]
        public SendReceiveDeviceDataProvider DataProvider = new SendReceiveDeviceDataProvider();

        private PosENUClass _U_Off = new PosENUClass();  // 接收机在东北天的相位中心偏差（PCO）

        //随机误差赋值
        public CalRan_Input pCalRan_Input;


        #region 观测误差配置

        private double _PseudoRanThH = 0.3;//不超过分米量级，界面设置
        private double _CarrRanThH = 0.003;//不超过毫米量级，界面设置
        private double _HWBias; //通道时延，界面设置，ns
        private ObsErrFlagClass _ErrFlag = new ObsErrFlagClass();

        #region 观测误差模型控制
        private ESatClkModelType _ObsSatclkModel;//卫星钟模型，界面设置
        private ESatClkModelType _ObsStaclkModel;//地面站钟模型，界面设置
        private IonSimModelType _ObsIonModel = IonSimModelType.球谐模型;//电离层模型，界面设置
        private ETroModelType _ObsTroModel;//对流层模型，界面设置
        private EMulModelType _ObsMulModel;//多路径模型，界面设置
        private ERelModelType _ObsRelModel;//相对论模型，界面设置
        private EOffModelType _ObsOffModel;//相位中心偏移模型，界面设置
        #endregion

        #endregion

        #endregion 

        #region 属性

        [XmlAttribute, Category("基本信息"), Description("")]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        [DescriptionAttribute("接收机相对于东北天的相位中心偏移量"), CategoryAttribute("基本信息"), PropertyOrder(5)]
        public PosENUClass U_Off
        {
            get { return _U_Off; }
            set { _U_Off = value; }
        }

        #region 观测信息配置

        [Category("观测数据仿真设置"), Description("截止高度角"), PropertyOrder(2)]
        public double Elelim
        {
            get { return _Elelim; }
            set { _Elelim = value; }
        }

        [Category("观测数据仿真设置"), Description("频点值"), PropertyOrder(1)]
        public double Frequency
        {
            get { return _Freq; }
            set { _Freq = value; }
        }

        #region 观测误差配置

        [Category("观测数据仿真设置"), Description("误差控制开关"), PropertyOrder(5)]
        public ObsErrFlagClass ErrFlag
        {
            get { return _ErrFlag; }
            set { _ErrFlag = value; }
        }

        [Category("观测数据仿真设置"), Description("伪距噪声量级"), PropertyOrder(3)]
        public double PseudoRanThH
        {
            get { return _PseudoRanThH; }
            set { _PseudoRanThH = value; }
        }

        [Category("观测数据仿真设置"), Description("载波相位噪声量级"), PropertyOrder(4)]
        public double CarrRanThH
        {
            get { return _CarrRanThH; }
            set { _CarrRanThH = value; }
        }

         [CategoryAttribute("观测数据仿真设置"), DescriptionAttribute("通道时延（ns）"), DisplayName("通道时延"), PropertyOrder(5)]
        public double HWBias
        {
            get { return _HWBias; }
            set { _HWBias = value; }
        }



        #endregion

        #region 观测误差模型

        /// <summary>
        /// 卫星钟差模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("卫星钟差模型"), DisplayName("SatclkModel"), PropertyOrder(6)]
        public ESatClkModelType ObsSatclkModel
        {
            get { return _ObsSatclkModel; }
            set { _ObsSatclkModel = value; }
        }

        /// <summary>
        /// 地面站钟差模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("地面站钟差模型"), DisplayName("StaclkModel"), PropertyOrder(7)]
        public ESatClkModelType ObsStaclkModel
        {
            get { return _ObsStaclkModel; }
            set { _ObsStaclkModel = value; }
        }


        /// <summary>
        /// 电离层模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("电离层模型"), DisplayName("IonModel"), PropertyOrder(8)]
        public IonSimModelType ObsIonModel
        {
            get { return _ObsIonModel; }
            set { _ObsIonModel = value; }
        }

        /// <summary>
        /// 对流层模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("对流层模型"), DisplayName("TroModel"), PropertyOrder(9)]
        public ETroModelType ObsTroModel
        {
            get { return _ObsTroModel; }
            set { _ObsTroModel = value; }
        }



        /// <summary>
        /// 多路径模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("多路径模型"), DisplayName("MulModel"), PropertyOrder(10)]
        public EMulModelType ObsMulModel
        {
            get { return _ObsMulModel; }
            set { _ObsMulModel = value; }
        }

        /// <summary>
        /// 相对论模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("相对论模型"), DisplayName("RelModel"), PropertyOrder(11)]
        public ERelModelType ObsRelModel
        {
            get { return _ObsRelModel; }
            set { _ObsRelModel = value; }
        }

        /// <summary>
        /// 相位中心偏移模型
        /// </summary>
        [XmlAttribute, Category("观测数据仿真设置"), DescriptionAttribute("相位中心偏移模型"), DisplayName("OffModel"), PropertyOrder(12)]
        public EOffModelType ObsOffModel
        {
            get { return _ObsOffModel; }
            set { _ObsOffModel = value; }
        }

        #endregion

        #endregion

        #endregion

        #region 方法       

        // 上行观测数据生成
        public void UpObsCal(int StationID, int SatID, UTCTime NowTime, out ObsReceiverOutput UpObsOutput)
        {
            ObsInput.CurTime = NowTime;
            Satellite Sat;
            ObsReceiverOutput TempObsOutput = new ObsReceiverOutput();
            double ErrValue = 0;

            #region 获取上行观测卫星位置

            SpaceSegment temp = new SpaceSegment();
            temp = (Parent.Parent.Parent.Parent as Scenario).SegmentColletion[0] as SpaceSegment;
            Sat = temp.ConstellationList[0].SatelliteCollection[SatID - 1];

            int SatPVListID = (int)Math.Floor((NowTime.JD - BDSimObject.GlobalStartTime.JD) * 86400.0 / Sat.Orbit.IntegrationParam.StepSize);
            int SendPVListID = SatPVListID;

            NodePosVel RealECIPV = new NodePosVel();
            double trpTime = (NowTime.JD - BDSimObject.GlobalStartTime.JD) * 86400.0; //需要差值的时刻(相对时间，单位秒)       
            RealECIPV = Sat.RealTimePV(NowTime);
            RealECIPV.Epoch = NowTime;

            #endregion

            #region 获取上行观测地面站位置信息(10个点)
            NodePosVel StationECFPos = new NodePosVel();

            double StaClkErr=0;
            MeteorologicalsParam Tro = new MeteorologicalsParam();

            foreach (var station in Parent.StationList)
            {
                if (station.Id == StationID)
                {
                    ObsInput.SendPos = new NodePosVel[10];

                    StationECFPos.X = station.Pos_XYZ.X;
                    StationECFPos.Y = station.Pos_XYZ.Y;
                    StationECFPos.Z = station.Pos_XYZ.Z;
                    StationECFPos.VX = 0;
                    StationECFPos.VY = 0;
                    StationECFPos.VZ = 0;

                    for (int k = 0; k < 10; k++)
                    {
                        UTCTime Temp;

                        double TempNowTime = (k - 4) * 30;  //30秒一个点
                        Temp.IntJD = ObsInput.CurTime.IntJD + Math.Floor(TempNowTime / 86400.0);
                        Temp.DouJD = ObsInput.CurTime.DouJD + TempNowTime / 86400.0 - Math.Floor(TempNowTime / 86400.0);
                        Temp.JD = Temp.IntJD + Temp.DouJD;
                        TimeSpaceDll.CAL2UTC(out Temp, 2);
                        StationECFPos.Epoch = Temp;

                        TimeSpaceDll.ECF2ECI(StationECFPos, 0, 0, out  ObsInput.SendPos[k]);
                    }

                    StaClkErr=station.RealTimeClkErr(NowTime);
                    station.GetMeteorological(NowTime);
                    Tro= station.StationMeteParam;
                    break;
                }
            }
  
            #endregion

            ObsInput.StaID = SatID;
            ObsInput.SatID = StationID;
            ObsInput.SendPosFlag = 1;

            /// 单个时刻可见星观测值
            NodePosVel SatOrbECF = new NodePosVel();
            TimeSpaceDll.ECI2ECF(RealECIPV, 0, 0, out  SatOrbECF);

            ObsInput.ReceiverPos = RealECIPV;

            if (true)//1 == CAccessCalDLL.StationAccess(StationECFPos, SatOrbECF, ECFtype.type_CGCS2000, _Elelim, out Ele, out Azi))
            {
                ObsInput.ObsErr = new double[2];
                //观测误差计算
                #region 误差计算
                if (_ErrFlag.IsSatClk)//卫星钟差
                {
                    ErrValue = Sat.RealTimeClkErr(NowTime) * 2.99792458E8;
                }
                else
                {
                    ErrValue = 0;
                }


                if (_ErrFlag.IsStaClk)
                {
                    ErrValue += StaClkErr * 2.99792458E8;
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsItro)//对流层误差
                {
                    CalTro_Input troinput = new CalTro_Input();
                    troinput.SatECFPos = new double[3];
                    troinput.UsePos = new double[3];
                    troinput.Tro = Tro;

                    troinput.SatECFPos[0] = SatOrbECF.x;
                    troinput.SatECFPos[1] = SatOrbECF.y;
                    troinput.SatECFPos[2] = SatOrbECF.z;
                    troinput.UsePos[0] = StationECFPos.x;
                    troinput.UsePos[1] = StationECFPos.y;
                    troinput.UsePos[2] = StationECFPos.z;

                    double DeltTro = 0;
                    int Itro = 1;
                    switch (ObsTroModel)
                    {
                        case ETroModelType.Hopfield:
                            Itro = 1;
                            break;
                        case ETroModelType.ImprovedHopfield:
                            Itro = 2;
                            break;
                        case ETroModelType.Saastamoinen:
                            Itro = 3;
                            break;
                    }
                    TropDLL.CalTro_output(troinput, Itro, out DeltTro);

                    ErrValue += DeltTro;
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsImul)
                {
                    double multiDelay = 0;
                    double[] UseECFPos = new double[3];
                    double[] SatECFPos = new double[3];
                    double MaxValue = 5;  //随机误差的最大值
                    double ele = 0;
                    double azi = 0;

                    SatECFPos[0] = SatOrbECF.x;
                    SatECFPos[1] = SatOrbECF.y;
                    SatECFPos[2] = SatOrbECF.z;

                    UseECFPos[0] = StationECFPos.x;
                    UseECFPos[1] = StationECFPos.y;
                    UseECFPos[2] = StationECFPos.z;

                    CalEleAziDLL.Cal_EleAzi(UseECFPos, SatECFPos, ref ele, ref azi);
                    MulPathDelayDLL.CalMultiPath(MaxValue, ele, ref multiDelay);

                    ErrValue += multiDelay;  
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsIoff)
                {
                    double DeltOff = 0;
                    caloff_input pCalOff_Input;

                    pCalOff_Input.CurTime = NowTime;

                    pCalOff_Input.SatECFPos = new double[3];
                    pCalOff_Input.SatECFPos[0] = SatOrbECF.x;
                    pCalOff_Input.SatECFPos[1] = SatOrbECF.y;
                    pCalOff_Input.SatECFPos[2] = SatOrbECF.z;

                    pCalOff_Input.UseECFPos = new double[3];
                    pCalOff_Input.UseECFPos[0] = StationECFPos.x;
                    pCalOff_Input.UseECFPos[1] = StationECFPos.y;
                    pCalOff_Input.UseECFPos[2] = StationECFPos.z;

                    pCalOff_Input.S_Off = new double[3];
                    pCalOff_Input.S_Off = Sat.PhaseOff;

                    pCalOff_Input.U_Off = new double[3];
                    pCalOff_Input.U_Off[0] = U_Off.E;
                    pCalOff_Input.U_Off[1] = U_Off.N;
                    pCalOff_Input.U_Off[2] = U_Off.U;

                    COffSetDLL.CalPhaseOffset_output(pCalOff_Input, 1, out DeltOff);
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsIrel)
                {
                    double DeltRel = 0.0;
                    RelDLL.CalRel_output(ObsInput.SendPos[4], 1, out DeltRel);
                    ErrValue += DeltRel;
                }
                else
                {
                    ErrValue += 0;
                }

                #endregion 误差计算

                ObsInput.Freq = _Freq;

                if (_ErrFlag.IsIion)//电离层误差计算
                {
                    CalIon_Input ioninput;
                    ioninput.Time = NowTime;
                    ioninput.SatECFPos = new double[3];
                    ioninput.SatECFPos[0] = SatOrbECF.x;
                    ioninput.SatECFPos[1] = SatOrbECF.y;
                    ioninput.SatECFPos[2] = SatOrbECF.z;
                    ioninput.UsePos = new double[3];
                    ioninput.UsePos[0] = StationECFPos.x;
                    ioninput.UsePos[1] = StationECFPos.y;
                    ioninput.UsePos[2] = StationECFPos.z;

                    CalIon_Output ionoutput;
                    int IIon = 1;
                    switch (ObsIonModel)
                    {
                        case IonSimModelType.球谐模型:
                            IIon = 1;
                            break;
                        case IonSimModelType.全球格网插值模型:
                            IIon = 2;
                            break;
                    }
                    IonTEC.CalIon_output(ioninput, IIon, out ionoutput);

                    double DeltIon = 0;
                    IonMapDLL.Ion_VTEC2DST(ionoutput.VTEC, ObsInput.Freq, ionoutput.Zenith, 1, out DeltIon);

                    ObsInput.ObsErr[0] = ErrValue + DeltIon;
                    ObsInput.ObsErr[1] = ErrValue - DeltIon;
                }
                else
                {
                    ObsInput.ObsErr[0] = ErrValue + 0;
                    ObsInput.ObsErr[1] = ErrValue - 0;
                }
                //通道时延
              //  ObsInput.ObsErr[0] += (Sat.SatObsErrFlag.SendHWBias - this.HWBias) * 1e-9 * 299792458;
              //  ObsInput.ObsErr[1] += (Sat.SatObsErrFlag.SendHWBias - this.HWBias) * 1e-9 * 299792458;

                int aa = CObsDataGenDLL.ObsRecvInit(ObsInput, out TempObsOutput);

                // pCalRan_Input.DeltRanThH = PseudoRanThH;
                //  pCalRan_Input.DeltRanThH = Sat.SatObsErrFlag.DeltRanThH; //观测误差只算接收机部分
                //  double PseudoRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);
                double PseudoRan = 0;

                pCalRan_Input.DeltRanThH = CarrRanThH;
                double CarrRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);
                TempObsOutput.SatObs.A_Pseudo_writein += PseudoRan;
                TempObsOutput.SatObs.A_Carri_writein += CarrRan;
            }
            UpObsOutput = TempObsOutput;
        }

        /// 下行观测数据生成
        public void DownObsCal(int StationID, int SatID, UTCTime NowTime, out ObsReceiverOutput DownObsOutput)
        {
            ObsInput.CurTime = NowTime;
            Satellite Sat;
            double ErrValue = 0;
            ObsReceiverOutput TempObsOutput = new ObsReceiverOutput();

            #region 获取下行观测地面站位置

            NodePosVel StationECIPos = new NodePosVel();
            NodePosVel StationECFPos = new NodePosVel();
           
            double StaClkErr = 0;
            MeteorologicalsParam Tro = new MeteorologicalsParam();         

            foreach (var station in Parent.StationList)
            {
                if (station.Id == StationID)
                {
                    StationECFPos.Epoch = ObsInput.CurTime;
                    StationECFPos.X = station.Pos_XYZ.X;
                    StationECFPos.Y = station.Pos_XYZ.Y;
                    StationECFPos.Z = station.Pos_XYZ.Z;
                    StationECFPos.VX = 0;
                    StationECFPos.VY = 0;
                    StationECFPos.VZ = 0;

                    TimeSpaceDll.ECF2ECI(StationECFPos, 0, 0, out  StationECIPos);
                    ObsInput.ReceiverPos = StationECIPos;

                    StaClkErr = station.RealTimeClkErr(NowTime);
                    station.GetMeteorological(NowTime);
                    Tro = station.StationMeteParam;   
                    
                    break;
                }
            }        

            #endregion

            #region 获取下行观测卫星10个点位置信息
            SpaceSegment temp = new SpaceSegment();
            temp = (Parent.Parent.Parent.Parent as Scenario).SegmentColletion[0] as SpaceSegment;
            Sat = temp.ConstellationList[0].SatelliteCollection[SatID - 1];

            NodePosVel[] SatPosMsg = new NodePosVel[10];
            int SatPVListID = (int)Math.Floor((NowTime.JD - BDSimObject.GlobalStartTime.JD) * 86400.0 / Sat.Orbit.IntegrationParam.StepSize);
            int SendPVListID = SatPVListID;
            if (SendPVListID >= 5 & (Sat.OrbitPVList.Count - SendPVListID) > 5)
            {
                for (int len = 0; len < 10; len++)
                {
                    SatPosMsg[len] = Sat.OrbitPVList[SendPVListID - 5 + len].SatPV_ECI;
                }
            }
            else if (SendPVListID < 5)
            {
                for (int len = 0; len < 10; len++)
                {
                    SatPosMsg[len] = Sat.OrbitPVList[len].SatPV_ECI;
                }
            }
            else
            {
                for (int len = 0; len < 10; len++)
                {
                    SatPosMsg[len] = Sat.OrbitPVList[Sat.OrbitPVList.Count - 10 + len].SatPV_ECI;
                }
            }

            #endregion

            ObsInput.StaID = StationID;
            ObsInput.SatID = SatID;
            ObsInput.SendPosFlag = 1;

            ObsInput.SendPos = new NodePosVel[10];
            ObsInput.SendPos = SatPosMsg;

            /// 单个时刻可见星观测值
            NodePosVel SatOrbECF = new NodePosVel();
            TimeSpaceDll.ECI2ECF(ObsInput.SendPos[4], 0, 0, out  SatOrbECF);                    
            
            if (true)//1== CAccessCalDLL.StationAccess(StationECFPos, SatOrbECF, ECFtype.type_CGCS2000, _Elelim, out Ele, out Azi))
            {
                ObsInput.ObsErr = new double[2];
                //观测误差计算
                #region 误差计算
                if (_ErrFlag.IsSatClk)//卫星钟差
                {
                    ErrValue = Sat.RealTimeClkErr(NowTime) * 2.99792458E8;
                }
                else
                {
                    ErrValue = 0;
                }

                if (_ErrFlag.IsStaClk)
                {
                    ErrValue += StaClkErr * 2.99792458E8;
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsItro)//对流层误差
                {
                    CalTro_Input troinput = new CalTro_Input();
                    troinput.SatECFPos = new double[3];
                    troinput.UsePos = new double[3];
                    troinput.Tro = Tro;

                    troinput.SatECFPos[0] = SatOrbECF.x;
                    troinput.SatECFPos[1] = SatOrbECF.y;
                    troinput.SatECFPos[2] = SatOrbECF.z;
                    troinput.UsePos[0] = StationECFPos.x;
                    troinput.UsePos[1] = StationECFPos.y;
                    troinput.UsePos[2] = StationECFPos.z;

                    double DeltTro = 0;
                    int Itro = 1;
                    switch (ObsTroModel)
                    {
                        case ETroModelType.Hopfield:
                            Itro = 1;
                            break;
                        case ETroModelType.ImprovedHopfield:
                            Itro = 2;
                            break;
                        case ETroModelType.Saastamoinen:
                            Itro = 3;
                            break;
                    }
                    TropDLL.CalTro_output(troinput, Itro, out DeltTro);

                    ErrValue += DeltTro;
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsImul)
                {
                    double multiDelay = 0;
                    double[] UseECFPos = new double[3];
                    double[] SatECFPos = new double[3];
                    double MaxValue = 5;  //随机误差的最大值
                    double ele = 0;
                    double azi = 0;

                    SatECFPos[0] = SatOrbECF.x;
                    SatECFPos[1] = SatOrbECF.y;
                    SatECFPos[2] = SatOrbECF.z;

                    UseECFPos[0] = StationECFPos.x;
                    UseECFPos[1] = StationECFPos.y;
                    UseECFPos[2] = StationECFPos.z;

                    CalEleAziDLL.Cal_EleAzi(UseECFPos, SatECFPos, ref ele, ref azi);
                    MulPathDelayDLL.CalMultiPath(MaxValue, ele, ref multiDelay);

                    ErrValue += multiDelay;  
                }
                else
                {
                    ErrValue += 0;
                }

                if (_ErrFlag.IsIoff)
                {
                    double DeltOff = 0;
                    caloff_input pCalOff_Input;

                    pCalOff_Input.CurTime = NowTime;

                    pCalOff_Input.SatECFPos = new double[3];
                    pCalOff_Input.SatECFPos[0] = SatOrbECF.x;
                    pCalOff_Input.SatECFPos[1] = SatOrbECF.y;
                    pCalOff_Input.SatECFPos[2] = SatOrbECF.z;

                    pCalOff_Input.UseECFPos = new double[3];
                    pCalOff_Input.UseECFPos[0] = StationECFPos.x;
                    pCalOff_Input.UseECFPos[1] = StationECFPos.y;
                    pCalOff_Input.UseECFPos[2] = StationECFPos.z;

                    pCalOff_Input.S_Off = new double[3];
                    pCalOff_Input.S_Off = Sat.PhaseOff;

                    pCalOff_Input.U_Off = new double[3];
                    pCalOff_Input.U_Off[0] = U_Off.E;
                    pCalOff_Input.U_Off[1] = U_Off.N;
                    pCalOff_Input.U_Off[2] = U_Off.U;

                    COffSetDLL.CalPhaseOffset_output(pCalOff_Input, 1, out DeltOff);
                }
                else
                {
                    ErrValue += 0;

                }

                if (_ErrFlag.IsIrel)
                {
                    double DeltRel = 0.0;
                    RelDLL.CalRel_output(ObsInput.SendPos[4], 1, out DeltRel);
                    ErrValue += DeltRel;
                }
                else
                {
                    ErrValue += 0;

                }

                #endregion 误差计算

                ObsInput.Freq = _Freq;

                if (_ErrFlag.IsIion)//电离层误差计算
                {
                    CalIon_Input ioninput;
                    ioninput.Time = NowTime;
                    ioninput.SatECFPos = new double[3];
                    ioninput.SatECFPos[0] = SatOrbECF.x;
                    ioninput.SatECFPos[1] = SatOrbECF.y;
                    ioninput.SatECFPos[2] = SatOrbECF.z;
                    ioninput.UsePos = new double[3];
                    ioninput.UsePos[0] = StationECFPos.x;
                    ioninput.UsePos[1] = StationECFPos.y;
                    ioninput.UsePos[2] = StationECFPos.z;

                    CalIon_Output ionoutput;
                    int IIon = 1;
                    switch (ObsIonModel)
                    {
                        case IonSimModelType.球谐模型:
                            IIon = 1;
                            break;
                        case IonSimModelType.全球格网插值模型:
                            IIon = 2;
                            break;
                    }
                    IonTEC.CalIon_output(ioninput, IIon, out ionoutput);

                    double DeltIon = 0;
                    IonMapDLL.Ion_VTEC2DST(ionoutput.VTEC, ObsInput.Freq, ionoutput.Zenith, 1, out DeltIon);

                    ObsInput.ObsErr[0] = ErrValue + DeltIon;
                    ObsInput.ObsErr[1] = ErrValue - DeltIon;
                }
                else
                {
                  
                    ObsInput.ObsErr[0] = ErrValue + 0;
                    ObsInput.ObsErr[1] = ErrValue - 0;
                }

                //通道时延
            //    ObsInput.ObsErr[0] += (-Sat.SatObsErrFlag.SendHWBias + this.HWBias) * 1e-9 * 299792458;
             //   ObsInput.ObsErr[1] += (-Sat.SatObsErrFlag.SendHWBias + this.HWBias) * 1e-9 * 299792458;

                int aa = CObsDataGenDLL.ObsRecvInit(ObsInput, out TempObsOutput);

                pCalRan_Input.DeltRanThH = PseudoRanThH;
                double PseudoRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);

                pCalRan_Input.DeltRanThH = CarrRanThH;
                double CarrRan = NoiseServiceDLL.CalRan_output(ref pCalRan_Input, 1);
                TempObsOutput.SatObs.A_Pseudo_writein += PseudoRan;
                TempObsOutput.SatObs.A_Carri_writein += CarrRan;
            }
            DownObsOutput = TempObsOutput;
        }

        #endregion

    }
}
